package com.dream.web.controller.web;

import com.dream.common.constans.Constants;
import com.dream.common.constans.RedisKeysDefine;
import com.dream.common.exception.RespErrorException;
import com.dream.common.utils.JsonUtils;
import com.dream.common.utils.ThreadContextUtil;
import com.dream.common.utils.ThreadPoolService;
import com.dream.common.utils.payutils.bean.WorkedRedPackageBean;
import com.dream.common.utils.payutils.bean.configuration.FunctionSwitchBean;
import com.dream.common.utils.payutils.bean.configuration.ReportResultBean;
import com.dream.dto.DataResponse;
import com.dream.dto.console.StatisticsSum;
import com.dream.dto.request.WebSocketBean;
import com.dream.dto.socket.SocketBean;
import com.dream.entity.GroupRules;
import com.dream.entity.PickUserInfoBean;
import com.dream.mapper.*;
import com.dream.net.socket.base.BaseSocketController;
import com.dream.service.basic.AsyncInvokeService;
import com.dream.service.basic.RedisCacheService;
import com.dream.web.aop.annotation.CommonResponse;
import com.dream.net.socket.base.SocketController;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import tk.mybatis.mapper.entity.Example;
import tk.mybatis.mapper.util.Sqls;

import javax.annotation.Resource;
import java.util.*;

@RestController
@RequestMapping("/api/controlPanel")
@Api(tags = "管理平台相关设置")
public class ConsoleController {

    @Resource
    private GroupRulesMapper groupRulesMapper;
    @Resource
    private SocketController socketController;
    @Resource
    private RedPackageSendMapper redPackageSendMapper;
    @Resource
    private RedPackagePickMapper redPackagePickMapper;
    @Resource
    private RedisCacheService redisCacheService;
    @Resource
    private AsyncInvokeService asyncInvokeService;

    @PostMapping(value = "/checkRechargeCode")
    @ApiOperation(value = "检测授权码有效性", response = DataResponse.class)
    public DataResponse checkRechargeCode(@RequestBody GroupRules groupRules) {
        //return procedureServiceImpl.checkRechargeCode(groupRules.getRechargeCode());
        return DataResponse.builderFailed("1");
    }


    @CommonResponse
    @GetMapping(value = "/getPackageRule")
    @ApiOperation(value = "获取当前登录用户规则", response = GroupRules.class)
    public Object getGroupPackageRules() {
        String userName = ThreadContextUtil.get("userName").toString();
        GroupRules groupRules = redisCacheService.getObject(RedisKeysDefine.CALC_RULE.concat(userName), GroupRules.class);
        if (groupRules == null) {
            groupRules = groupRulesMapper.selectByPrimaryKey(userName);
            if (groupRules == null) {
                groupRules = new GroupRules();
            }
        }
        if (groupRules.getPackageRule() == null || "".equals(groupRules.getPackageRule())) {
            groupRules.setPackageRule(Constants.CONFIGURATION_DEFAULT_RULE);
        }
        if (groupRules.getFeatureSwitch() == null || "".equals(groupRules.getFeatureSwitch())) {
            FunctionSwitchBean functionSwitchBean = new FunctionSwitchBean();
            groupRules.setFeatureSwitch(JsonUtils.toJSONString(functionSwitchBean));
        }
        if (groupRules.getPrizeText() == null || "".equals(groupRules.getPrizeText())) {
            ReportResultBean reportResultBean = new ReportResultBean();
            reportResultBean.bill = Constants.REPORT_TEXT_COMMAND;
            reportResultBean.sweep = Constants.REPORT_TEXT;
            groupRules.setPrizeText(JsonUtils.toJSONString(reportResultBean));
        }
        return groupRules;
    }


    @CommonResponse
    @ApiOperation(value = "当前登录用户设置规则", response = DataResponse.class)
    @PostMapping("/putRule")
    public Object putConfigVal(@RequestBody GroupRules groupRules) {
        String userName = ThreadContextUtil.get("userName").toString();
        groupRules.setUserName(userName);

        if (groupRulesMapper.existsWithPrimaryKey(groupRules)) {
            groupRulesMapper.updateByPrimaryKeySelective(groupRules);
        } else {
            groupRulesMapper.insertSelective(groupRules);
        }
        redisCacheService.setObject(RedisKeysDefine.CALC_RULE.concat(userName), groupRulesMapper.selectByPrimaryKey(userName));
        return 0;
    }


    @CommonResponse
    @ApiOperation(value = "首页进入时各类数据汇总", response = StatisticsSum.class)
    @GetMapping("/pageGatherData")
    public Object pageGatherData() {
        String userName = ThreadContextUtil.get("userName").toString();
        StatisticsSum statisticsSum = redisCacheService.getObject(RedisKeysDefine.STATISTICS_PANEL.
                concat(userName), StatisticsSum.class);
        if (statisticsSum == null) {
            statisticsSum = redPackageSendMapper.selectSumByUser(userName);
            statisticsSum.groupRedPackList = asyncInvokeService.getMergedGroupRedPackList(userName);
        }
        statisticsSum.userInfo = redisCacheService.get(RedisKeysDefine.APP_USER_INFO.concat(userName));
        Set<String> historyMsg = redisCacheService.zSetOperations.reverseRangeByScore(RedisKeysDefine.IM_MSG.concat(userName),
                0, System.currentTimeMillis(), 0, 100);
        if (!CollectionUtils.isEmpty(historyMsg)) {
            List<String> reverseList = new ArrayList<>(historyMsg);
            Collections.reverse(reverseList);
            statisticsSum.historyMsg = reverseList;
        } else {
            statisticsSum.historyMsg = new ArrayList<>();
        }
        statisticsSum.isOnline = BaseSocketController.socketUserChannels.containsKey(userName);

        statisticsSum.workedRedPackageBean = null;
        return statisticsSum;
    }


    @CommonResponse
    @ApiOperation(value = "发送消息", response = DataResponse.class)
    @PostMapping("/sendWebCommand")
    public Object sendWebCommand(@RequestBody WebSocketBean<String> webSocketBean) {
        String userName = ThreadContextUtil.get("userName").toString();
        if (StringUtils.isEmpty(webSocketBean.data)) {
            throw new RespErrorException("空白消息!");
        }

        if (!SocketController.socketUserChannels.containsKey(userName)) {
            throw new RespErrorException("请打开app或者划掉app重新打开");
        }

        asyncInvokeService.msgUnityWrite(userName, webSocketBean.data);

        SocketBean socketBean = new SocketBean();
        socketBean.command = webSocketBean.command;
        socketBean.data = webSocketBean.data;
        ThreadPoolService.execute(() -> socketController.sendCommand(userName, socketBean));

        return 1;
    }


    @CommonResponse
    @ApiOperation(value = "清空数据", response = DataResponse.class)
    @GetMapping("/clearUserData")
    public Object clearUserData() {
        String userName = ThreadContextUtil.get("userName").toString();
        //清空这个用户的伐包和枪包数据以及聊天消息
        redPackageSendMapper.deleteByExample(Example.builder(WorkedRedPackageBean.class).andWhere(Sqls.custom().andEqualTo("bijiAccount", userName)).build());
        redPackagePickMapper.deleteByExample(Example.builder(PickUserInfoBean.class).andWhere(Sqls.custom().andEqualTo("bijiAccount", userName)).build());
        redisCacheService.del(RedisKeysDefine.IM_MSG.concat(userName));
        redisCacheService.del(RedisKeysDefine.STATISTICS_PANEL.concat(userName));
        /*userFieldMapper.deleteByExample(Example.builder(UserField.class).andWhere(Sqls.custom()
        .andEqualTo("userName",userName).andEqualTo("optionKey",Constants.IM_MSG)).build());*/
        return 1;
    }


    @CommonResponse
    @ApiOperation(value = "历史消息", response = DataResponse.class)
    @GetMapping("/historyMessage/{optionTime}")
    public Object historyMessage(@PathVariable Long optionTime) {
        String userName = ThreadContextUtil.get("userName").toString();
        Set<String> historyMsg = redisCacheService.zSetOperations.reverseRangeByScore(RedisKeysDefine.IM_MSG.concat(userName),
                0, optionTime, 1, 100);
        if (!CollectionUtils.isEmpty(historyMsg)) {
            List<String> reverseList = new ArrayList<>(historyMsg);
            Collections.reverse(reverseList);
            return reverseList;
        }
        return Collections.emptyList();
    }
}
